﻿using System.Security.Claims;
using System.Text;
using Common.Identity;
using JWT;
using JWT.Algorithms;
using JWT.Builder;
using JWT.Serializers;
using Microsoft.OpenApi.Extensions;

namespace Common.Util;

/// <summary>
/// Jwt Token 工具, 加密算法(HS256)
/// </summary>
public static class TokenUtil
{
    private static readonly IJwtAlgorithm Hs256 = new HMACSHA256Algorithm();
    private static readonly IJsonSerializer CustomJsonSerializer = new CustomJwtTokenJsonSerializer();

    /// <summary>
    /// 使用密码解码JwtToken, 
    /// </summary>
    /// <param name="token">jwt token</param>
    /// <param name="secret">密码</param>
    /// <returns>UserInfo对象</returns>
    public static UserInfo Decode(string token, string secret)
    {
        return JwtBuilder.Create().WithAlgorithm(Hs256)
            .WithSecret(Encoding.UTF8.GetBytes(secret))
            .WithJsonSerializer(CustomJsonSerializer)
            .MustVerifySignature().Decode<UserInfo>(token);
    }

    public static string EncodeWithHs256(string secret, DateTimeOffset exp, Dictionary<string, object>? payload)
    {
        var builder = JwtBuilder.Create().WithAlgorithm(Hs256)
            .WithSecret(Encoding.UTF8.GetBytes(secret));

        builder.AddClaim(ClaimName.ExpirationTime, exp.ToUnixTimeSeconds());

        payload?.Remove(ClaimName.ExpirationTime.GetDisplayName());
        if (payload == null) return builder.Encode();
        foreach (var keyValuePair in payload)
        {
            builder.AddClaim(keyValuePair.Key, keyValuePair.Value);
        }

        return builder.Encode();
    }

    public static void Verify(string token, string secret)
    {
        Decode(token, secret);
    }

    /// <summary>
    /// 使用密码解码Jwt.Body为Dictionary对象
    /// </summary>
    /// <param name="token">jwt token</param>
    /// <param name="secret">密码</param>
    /// <returns>Dictionary</returns>
    public static Dictionary<string, object> DecodeToDictionary(string token, string secret)
    {
        return JwtBuilder.Create().WithAlgorithm(new HMACSHA256Algorithm() { })
            .WithSecret(Encoding.UTF8.GetBytes(secret))
            .MustVerifySignature().Decode<Dictionary<string, object>>(token);
    }


    public static UserInfo UnsafeDecode(string token)
    {
        return JwtBuilder.Create()
            .WithJsonSerializer(CustomJsonSerializer)
            .DoNotVerifySignature().Decode<UserInfo>(token);
    }

    public static Dictionary<string, object> UnsafeDecodeToDictionary(string token)
    {
        return JwtBuilder.Create()
            .WithJsonSerializer(CustomJsonSerializer)
            .DoNotVerifySignature().Decode<Dictionary<string, object>>(token);
    }
}